<?php
date_default_timezone_set("Asia/Shanghai");
//设置socket连接不超时
//ini_set('default_socket_timeout', -1);
require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Worker;
use PHPSocketIO\SocketIO;
use Workerman\MySQL\Connection;
use Workerman\Lib\Timer;

$config = require_once __DIR__ . '/config.php';
Worker::$stdoutFile = './stdout.log';
//全局变量 所有连接的box数组
$box_sockets;

// define('HEARTBEAT_TIME',3.5);
//创建socket.io服务端，监听12345端口
$io = new SocketIO(12120);

$io->on('workerStart', function () use ($io) {
    // 将db实例存储在全局变量中(也可以存储在某类的静态成员中)
    global $mysql, $redis, $config;
    try {
        $config = require __DIR__ . '/config.php';
        //初始化mysql
        $mysql = new Connection($config['mysql']['db_host'], $config['mysql']['db_port'],  $config['mysql']['db_user'], $config['mysql']['db_pass'], $config['mysql']['db_database']);
        //初始化redis
        $redis = new Redis();
        $redis->connect($config['redis']['db_host'], $config['redis']['db_port']);
        Timer::add(0.1, function()use($redis, $io){
            $data = json_decode($redis->rPop('meeting_transfer'), true);
            $io->to($data['mid'])->emit('get audio info', $data['transfer']);
        });
    } catch (\Exception $e) {
        echo $e;
    }
});
function callback($redis, $chan, $msg)
{
    try {
        switch ($chan) {
            case 'send audio info':
                sendAudioInfo($msg);
                break;
            default:
                break;
        }
    } catch (\Exception $e) {
        echo $e->getMessage();
        return;
    }
}
function sendAudioInfo($msg)
{
    //echo $msg . "\n";
    global $io;
    $config = require __DIR__ . '/config.php';
    //初始化mysql
    $mysql = new Connection($config['mysql']['db_host'], $config['mysql']['db_port'],  $config['mysql']['db_user'], $config['mysql']['db_pass'], $config['mysql']['db_database']);
    //初始化redis
    $redis = new Redis();
    $redis->connect($config['redis']['db_host'], $config['redis']['db_port']);
    //校验数据
    $msg_data = json_decode($msg, true);
    if (!$msg_data) {
        //如果数据格式不正确，返回错误信息
        throw new Exception("数据格式不正确。。");
    }
    //获取meetingid
    $mid = $msg_data['meeting_id'];
    //获取meeting对应表的lid
    $lid = $redis->hGet('meeting_to_lid', $mid);
    //判断meeting是否储存在对应表id的hash中
    if (!$lid) {
        //如果不存在则 查找并添加入hash
        $lid = $mysql->select('id')->from('rszh_meeting_live_speech')->where('meeting_tag = :mid')->bindValues(['mid' => $mid])->query();
        //如果不在数据库，则return
        if (empty($lid)) {
            throw new Exception("会议id - $mid 的文件在数据库不存在");
        }
        $lid = $lid[0]['id'];
        $redis->hSet('meeting_to_lid', $mid, $lid);
    }
    //数据处理
    $transfer = [
        'or_txt' => $msg_data['raw_text'],
        'ed_txt' => '',
        //'url' => $msg_data['url'],
        'url' => $msg_data['url'] ? substr($msg_data['url'], strpos($msg_data['url'], '/data/audio_file/')) : '',
        'paly_time' => $msg_data['pcmtime'],
        'status' => $msg_data['end_of_speech'],
        'timestamp' => $msg_data['timestamp']
        //'sorting' => $sorting + 0,
    ];
    $pagh = false;
    //初始化
    $sorting = 1;
    //查看储存该转写结果的状态是否存在
    if (!$redis->hGet($mid . "_state", 'lower')) {
        //不存在则 创建string储存结果状态
        //string
        $redis->hMSet($mid . "_state", ['subsection' => 0, 'lower' => $sorting, 'editstate' => 0, 'lastTime' => 0]);
        $redis->expire($mid . "_state", 60 * 60 * 24);
        //上传web
    }

    //如果存在则判断end_of_speech是否为1
    if ($msg_data['end_of_speech']) {
        //获取当前排序
        $sorting = $redis->hGet($mid . "_state", 'lower');
        //修改meeting_state
        $redis->hSet($mid . "_state", 'lower', $sorting + 1);
        $redis->expire($mid . "_state", 60 * 60 * 24);
        //该句结束，则储存hash
        $transfer['sorting'] = $sorting;
        //分段准备 redis中加入文字数量字段 end_of_speech为1则计算该段落总字数
        $txtCount = ($redis->hGet($mid . "_state", 'txtCount') ?: 0) + mb_strlen($transfer['or_txt'], 'utf8');
        //判断分段条件
        $transfer['sc'] = $redis->hGet($mid . "_state", 'subsection');
        if ($txtCount >= 100 && preg_match("/(\。)$/", $transfer['or_txt'])) {
            $redis->hIncrBy($mid . "_state", 'subsection', 1);
            $txtCount = 0;
            //分段
            $br = [
                'or_txt' => '<br>',
                'ed_txt' => '',
                'url' => '',
                'paly_time' => 0,
                'status' => 1,
                'timestamp' => '',
                'sc' => $transfer['sc']
            ];
            $pagh = true;
        }
        //更新当前文字数量
        $redis->hSet($mid . "_state", 'txtCount', $txtCount);

        //hash
        $redis->hSet($mid, $sorting, json_encode($transfer, JSON_UNESCAPED_UNICODE));
        //$redis->hSet($mid, $sorting, json_encode($transfer));
        $redis->expire($mid, 60 * 60 * 24);
        //并且存入数据库
        $save = [
            "lid" => $lid,
            "transfer" => $transfer['or_txt'],
            "editor" => $transfer['ed_txt'],
            "url" => $transfer['url'],
            "pcmtime" => $transfer['paly_time'] . '',
            "sorting" => $sorting + 0,
            "subsection" => $transfer['sc'],
            "create_time" => time()
        ];
        //判断是否成功以后加
        $lid = $mysql->insert('rszh_meeting_convert')->cols($save)->query();
    }
    ////如果存在end_of_speech为0
    else {
        //获取当前排序
        $sorting = $redis->hGet($mid . "_state", 'lower');
        $transfer['sorting'] = $sorting;
        //获取当前结果hash中对应的数据
        $result_json = $redis->hGet($mid, $sorting);
        //判断当前结果数据和新上传的值是否相同
        if ($result_json) {
            $result = json_decode($result_json, true);
            if ($result['or_txt'] == $transfer['or_txt']) {
                return;
            }
            $transfer['sc'] = $redis->hGet($mid . "_state", 'subsection');
        }
        //如果值不同，存入结果hash
        $redis->hSet($mid, $sorting, json_encode($transfer, JSON_UNESCAPED_UNICODE));
        //$redis->hSet($mid, $sorting, json_encode($transfer));
        $redis->expire($mid, 60 * 60 * 24);
    }


    //传给web
    //$io->to($mid)->emit('get audio info', $transfer);
    $msg = [
        'mid' => $mid,
        'transfer' => $transfer
    ];
    $redis->lPush('meeting_transfer', json_encode($msg));
    if ($pagh) {
        $msg = [
            'mid' => $mid,
            'transfer' => $br
        ];
        //$io->to($mid)->emit('get audio info', $br);
        $redis->lPush('meeting_transfer', json_encode($msg));
    }
};
//当有客户端连接
$io->on('connection', function ($socket) use ($io) {
    global $redis;
    // if ($redis->hGetAll('front')) {
    //     $socket->emit('front config', json_decode($redis->get('front'), true));
    // } 
    //echo '连接' . "\n";

    $socket->on("bind box", function ($data) use ($socket) {
        echo 'bind';
        global $box_sockets;
        if (!($data = json_decode($data, true))) {
            $socket->emit('boxError', "传递参数有错");
            return;
        }
        $socket->box = isset($box_sockets[$data['did']]) ? $box_sockets[$data['did']] : false;
        if ($socket->box) {
            //状态去文档看
            $status = ['1' => '0003', '2' => '0001', '3' => '0004'];
            //$box_sockets[$data['did']]->web = $socket;
            $socket->join("box-" . $data['did']);
            $socket->emit('speech status', array('token' => "rjjgdzjmbsyzxdrlcblmzgjhwhgxtdxq", 'meeting_id' => $socket->box->mid ?: "", 'status' => $socket->box->status, 'code' => $status[$socket->box->status]));
        } else {
            $socket->emit('speech status', array('token' => "rjjgdzjmbsyzxdrlcblmzgjhwhgxtdxq", 'status' => 0, 'code' => '0000'));
        }
    });

    $socket->on("command", function ($data) use ($socket) {
        global $box_sockets;
        if (!($data = json_decode($data, true))) {
            return;
        }
        if ($socket->box) {
            $socket->box->emit("boxcommand", json_encode(array("token" => "rjjgdzjmbsyzxdrlcblmzgjhwhgxtdxq", "code" => $data['code'] ? $data['code'] : '0404')));
        } else {
            $socket->emit('speech status', array('token' => "rjjgdzjmbsyzxdrlcblmzgjhwhgxtdxq", 'status' => 0, 'code' => '0000'));
        }
    });

    $socket->on('boxresponse', function ($data) use ($socket, $io) {
        global $redis;
        $data = json_decode($data, true);
        switch ($data['status']) {
            case 1:
                if ($socket->mid == $data['mid']) {
                    $socket->status = 4;
                    $socket->mid = $data['mid'];
                } else {
                    $socket->status = $data['status'];
                    $socket->mid = $data['mid'];
                }
                break;
            case 2:
                $socket->status = $data['status'];
                $socket->mid = "";
                break;
            case 3:
            case 4:
                $socket->status = $data['status'];
                $socket->mid = $data['mid'];
                break;
            default:
                return;
        }
        //$info = json_encode(['mid'=>$socket->mid, 'status' => $socket->status]);
        //$redis->hset("Box_queue", $socket->did,$info);
        //状态去文档看
        $status = ['1' => '0003', '2' => '0001', '3' => '0004', '4' => '0003'];
        if ($socket->did) {
            $io->to("box-" . $socket->did)->emit('speech status', array('token' => "rjjgdzjmbsyzxdrlcblmzgjhwhgxtdxq", 'meeting_id' => $data['mid'], 'status' => $socket->status, 'code' => $status[$socket->status]));
        }
    });

    $socket->on('boxexception', function ($data) use ($socket) {
        if ($socket->web) {
            //$socket->web->emit('exception', $data);
        }
    });



    //打印字 用户登录
    //登录功能 上传token userid meetingid
    $socket->on("get audio history", function ($msg) use ($socket) {
        //echo $msg;
        global $redis, $mysql;
        //判断$msg是否为json
        $msg_data = json_decode($msg, true);
        if (!$msg_data) {
            echo "格式不准确";
            return;
        }
        //获取$msg_data中的用户验证信息
        //$auth_key = $msg_data['token'];

        //meetingid设置
        $mid = $msg_data['meeting_id'];
        //获取当前录音转写状态
        $lid = $mysql->select('end_time')->from('rszh_meeting_live_speech')->where('meeting_tag = :mid')->bindValues(['mid' => $mid])->query();
        //接收历史记录
        //historical($mid);
        {
            //初始化发送的历史记录接送、字符串
            $dispatch = [];
            $br = [
                'or_txt' => '<br>',
                'ed_txt' => '',
                'url' => '',
                'paly_time' => 0,
                'status' => 1,
                'timestamp' => '',
                'sc' => 0
            ];
            $dispatch[] = json_encode($br);
            //获取结果hash中的结果
            //hVals转换结果乱序
            //$dispatch = $redis->hVals($mid);
            $count = $redis->hget($mid . '_state', 'lower') - 1;
            for ($i = 1; $i <= $count; $i++) {
                $result = $redis->hget($mid, $i);
                $result_la = $redis->hget($mid, $i - 1);
                $result_arr = json_decode($result, true);
                $result_la_arr = json_decode($result_la, true);

                if ($result_arr['sc'] != $result_la_arr['sc']) {
                    $br = [
                        'or_txt' => '<br>',
                        'ed_txt' => '',
                        'url' => '',
                        'paly_time' => 0,
                        'status' => 1,
                        'timestamp' => '',
                        'sc' => $result_la_arr['sc'] ? $result_la_arr['sc'] : 0

                        //'sorting' => $sorting + 0,
                    ];
                    $dispatch[] = json_encode($br);
                }
                $dispatch[] = $redis->hget($mid, $i);
            }
            //返回给连接用户的值
            $data = [
                'list' => $dispatch,
                'total' => count($dispatch)
            ];
        }
        $socket->emit('get audio history', $data);
        //$socket->broadcast->emit('get audio history', $data);
    });

    //web加入meetingid的组，并实时获取在线转写的消息
    $socket->on('get audio info', function ($msg) use ($socket) {
        //判断$msg是否为json
        $msg_data = json_decode($msg, true);
        if (!$msg_data) {
            echo "格式不准确";
            return;
        }
        //获取$msg_data中的用户验证信息
        //$auth_key = $msg_data['token'];

        //meetingid设置
        $mid = $msg_data['meeting_id'];
        //加入群组
        $socket->emit('prompt message', "加入" . $mid . "组");
        $socket->join($mid);
    });

    $socket->on(
        'front config',
        function ($data) use ($socket) {
            global $redis;
            if (!$data['id']) {
                return;
            }
            $id = $data['id'];
            unset($data['id']);
            foreach ($data as $k => $v) {
                $redis->hSet('front_' . $id, $k, $v);
            }
            $socket->emit('front config', 'success');
        }
    );

    $socket->on('get front', function ($data) use ($socket) {
        global $redis;
        $front = $redis->hGetAll('front_' . $data['id']);
        if ($front) {
            $socket->emit('front config', $front);
        }
    });


    //转写端链接 后发送消息
    $socket->on('send audio info', function ($msg) use ($socket, $io) {
        try {
            //echo $msg . "\n";
            global $mysql, $redis;
            //校验数据
            $msg_data = json_decode($msg, true);
            if (!$msg_data) {
                //如果数据格式不正确，返回错误信息
                $socket->emit('receive state', '{code:201,message:"数据格式不正确",type:"send audio info"}');
                return;
            }
            //给语音服务器发送接收状态
            $socket->emit('receive state', '{code:200,message:"success",type:"send audio info"}');
            //获取meetingid
            $mid = $msg_data['meeting_id'];
            //获取meeting对应表的lid
            $lid = $redis->hGet('meeting_to_lid', $mid);
            //判断meeting是否储存在对应表id的hash中
            if (!$lid) {
                //如果不存在则 查找并添加入hash
                $lid = $mysql->select('id')->from('rszh_meeting_live_speech')->where('meeting_tag = :mid')->bindValues(['mid' => $mid])->query();
                //如果不在数据库，则return
                if (empty($lid)) {
                    $socket->emit('receive state', '{code:202,message:"未找到meetingid",type:"send audio info"}');
                    return;
                }
                $lid = $lid[0]['id'];
                $redis->hSet('meeting_to_lid', $mid, $lid);
            }
            //数据处理
            $transfer = [
                'or_txt' => $msg_data['raw_text'],
                'ed_txt' => '',
                //'url' => $msg_data['url'],
                'url' => $msg_data['url'] ? substr($msg_data['url'], strpos($msg_data['url'], '/data/audio_file/')) : '',
                'paly_time' => $msg_data['pcmtime'],
                'status' => $msg_data['end_of_speech'],
                'timestamp' => $msg_data['timestamp']
                //'sorting' => $sorting + 0,
            ];
            $pagh = false;
            //初始化
            $sorting = 1;
            //查看储存该转写结果的状态是否存在
            if (!$redis->hGet($mid . "_state", 'lower')) {
                //不存在则 创建string储存结果状态
                //string
                $redis->hMSet($mid . "_state", ['subsection' => 0, 'lower' => $sorting, 'editstate' => 0, 'lastTime' => 0]);
                $redis->expire($mid . "_state", 60 * 60 * 24);
                //上传web
            } else {
                //如果存在则判断end_of_speech是否为1
                if ($msg_data['end_of_speech']) {
                    //获取当前排序
                    $sorting = $redis->hGet($mid . "_state", 'lower');
                    //修改meeting_state
                    $redis->hSet($mid . "_state", 'lower', $sorting + 1);
                    $redis->expire($mid . "_state", 60 * 60 * 24);
                    //该句结束，则储存hash
                    $transfer['sorting'] = $sorting;
                    //分段准备 redis中加入文字数量字段 end_of_speech为1则计算该段落总字数
                    $txtCount = ($redis->hGet($mid . "_state", 'txtCount') ?: 0) + mb_strlen($transfer['or_txt'], 'utf8');
                    //判断分段条件
                    $transfer['sc'] = $redis->hGet($mid . "_state", 'subsection');
                    if ($txtCount >= 100 && preg_match("/(\。)$/", $transfer['or_txt'])) {
                        $redis->hIncrBy($mid . "_state", 'subsection', 1);
                        $txtCount = 0;
                        //分段
                        $br = [
                            'or_txt' => '<br>',
                            'ed_txt' => '',
                            'url' => '',
                            'paly_time' => 0,
                            'status' => 1,
                            'timestamp' => '',
                            'sc' => $transfer['sc']
                        ];
                        $pagh = true;
                    }
                    //更新当前文字数量
                    $redis->hSet($mid . "_state", 'txtCount', $txtCount);

                    //hash
                    $redis->hSet($mid, $sorting, json_encode($transfer, JSON_UNESCAPED_UNICODE));
                    //$redis->hSet($mid, $sorting, json_encode($transfer));
                    $redis->expire($mid, 60 * 60 * 24);
                    //并且存入数据库
                    $save = [
                        "lid" => $lid,
                        "transfer" => $transfer['or_txt'],
                        "editor" => $transfer['ed_txt'],
                        "url" => $transfer['url'],
                        "pcmtime" => $transfer['paly_time'] . '',
                        "sorting" => $sorting + 0,
                        "subsection" => $transfer['sc'],
                        "create_time" => time()
                    ];
                    //判断是否成功以后加
                    $lid = $mysql->insert('rszh_meeting_convert')->cols($save)->query();
                }
                ////如果存在end_of_speech为0
                else {
                    //获取当前排序
                    $sorting = $redis->hGet($mid . "_state", 'lower');
                    $transfer['sorting'] = $sorting;
                    //获取当前结果hash中对应的数据
                    $result_json = $redis->hGet($mid, $sorting);
                    //判断当前结果数据和新上传的值是否相同
                    if ($result_json) {
                        $result = json_decode($result_json, true);
                        if ($result['or_txt'] == $transfer['or_txt']) {
                            return;
                        }
                        $transfer['sc'] = $redis->hGet($mid . "_state", 'subsection');
                    }
                    //如果值不同，存入结果hash
                    $redis->hSet($mid, $sorting, json_encode($transfer, JSON_UNESCAPED_UNICODE));
                    //$redis->hSet($mid, $sorting, json_encode($transfer));
                    $redis->expire($mid, 60 * 60 * 24);
                }
            }

            //传给web
            $io->to($mid)->emit('get audio info', $transfer);
            if ($pagh) {
                $io->to($mid)->emit('get audio info', $br);
            }
        } catch (\Exception $e) {
            echo $e->getMessage();
        }
    });

    $socket->on('disconnect', function ($data) use ($socket) {
        global $mysql, $box_sockets;
        if ($socket->did) {
            if (isset($box_sockets[$socket->did])) {
                if ($box_sockets[$socket->did] == $socket) {
                    $quary = "UPDATE `rszh_equipment` SET `connection`= 2,`update_time`=" . "'" . time() . "'" . " WHERE equipmentid = " .     "'" . $socket->did . "'";
                    $mr = $mysql->query($quary);
                    unset($box_sockets[$socket->did]);
                }
            }
            echo "\n" . $socket->did . "断开\n";
        }
    });

    //盒子功能
    $socket->on('boxlogin', function ($data) use ($socket) {
        global $box_sockets, $mysql, $redis;
        echo $data;
        if (!$msg = json_decode($data, true)) {
            return;
        }
        //校验 记录日志
        foreach ($msg as $value) {
            if (!$value) {
                return;
            }
        }

        $socket->did = $msg['box_id'];
        $quary = "UPDATE `rszh_equipment` SET `connection`= 1,`update_time`=" . "'" . time() . "'" . " WHERE equipmentid = " . $msg['box_id'];
        $mr = $mysql->query($quary);
        //更新存入数据库
        // if (($box_info = $redis->hget("Box_queue", $msg['box_id']))) {
        //     $info = json_decode($box_info, true);
        //     $socket->mid = $info['mid'];
        //     $socket->status = $info['status'];
        // } else {
        //     $socket->mid = "";
        //     $socket->status = 2;
        // }
        $socket->mid = "";
        $socket->status = 2;
        //加入boxsocket队列中
        $box_sockets[$msg['box_id']] = $socket;
    });
    $socket->on('boxlogout', function ($data) use ($socket) {
        global $mysql;
        if ($socket->did) {
            $quary = "UPDATE `rszh_equipment` SET `connection`= 2,`update_time`=" . "'" . time() . "'" . " WHERE equipmentid = " . "'" . $socket->did . "'";
            $mr = $mysql->query($quary);
            $socket->did = null;
            $socket->disconnect();
            echo $socket->did . '登出' . "\n";
        }
    });
    $socket->on('boxtranstart', function ($data) use ($socket) {
    });
    $socket->on('boxtranstatus', function ($data) use ($socket) {
        global $mysql;
        //echo $data;
        $msg = json_decode($data, true);
        if (!$msg) {
            return;
        }
        $list = json_decode($msg['filelist'], true);
        if (!$list) {
            return;
        }
        $filelist = array();
        try {
            foreach ($list as $meeting_id) {
                $real_query = "select id,transition_state,filename,is_manual from `rszh_meeting_live_speech` where meeting_tag='" . $meeting_id . "'";
                $result = $mysql->query($real_query);
                if (!$result) {
                    $filelist[$meeting_id] = [
                        "filename" => '',
                        "transtatus" => '',
                        "transpersent" => ''
                    ];
                } else {
                    $filename = $result[0]['filename'];
                    if ($result[0]['is_manual'] == 1) {
                        $filename = $filename . '.pcm';
                    }
                    $filelist[$meeting_id] = [
                        "filename" => $filename,
                        "transtatus" => $result[0]['transition_state'] == 2 ? 2 : 1,
                        "transpersent" => $result[0]['transition_state'] == 2 ? "100%" : "0%"
                    ];
                }
            }
        } catch (\Exception $e) {
            echo $e->getMessage();
        }
        $return = [
            'token' => $msg['token'],
            'filelist' => $filelist
        ];
        //var_dump($return);
        $return = json_encode($return);
        $socket->emit('boxtranstatus', $return);
    });


    //加密狗功能测试
    $socket->on('send soft dog info', function ($msg) use ($socket) {
        try {
            global $mysql, $redis;
            //echo $msg . "\n";
            $msg = json_decode($msg, true);
            if (!$msg) {
                $socket->emit('receive state', '{code:201,message:"数据格式不正确",type:"send soft dog info"}');
                return;
            }
            //储存加密狗设置
            $result = $redis->hMSet('soft_dog', ['key_id' => $msg['key_id'], 'product_name' => $msg['product_name'], 'soft_dog' => $msg['soft_dog'], 'update_time' => time()]);
            //储存到数据库
            $is_exist = $mysql->select("*")->from('rszh_soft_dog')->where('id= :id')->bindValues(array('id' => 1))->row();
            if ($is_exist) {
                $quary = "UPDATE `rszh_soft_dog` SET `key`=" . "'" . $msg['key_id'] . "'" . ",`name`=" . "'" . $msg['product_name'] . "'" . ",`brand`=" . "'" . $msg['soft_dog'] . "'" . ",`update_time`=" . "'" . time() . "'" . " WHERE ID=1";
                $mr = $mysql->query($quary);
            } else {
                $quary = "INSERT INTO `rszh_soft_dog` (`key`,`name`,`brand`,`create_time`,`update_time`) VALUES (" . "'" . $msg['key_id'] . "'" . "," . "'" . $msg['product_name'] . "'" . "," . "'" . $msg['soft_dog'] . "'" . "," . "'" . time() . "'" . "," . "'" . time() . "'" . ")";
                $mr = $mysql->query($quary);
            }
            if ($result) {
                $socket->emit('receive state', '{code:200,message:"success",type:"send soft dog info"}');
            }
        } catch (\Exception $e) {
            echo $e->getMessage();
        }
    });

    $socket->on('edit', function ($msg) use ($socket) {
        try {
            global $mysql, $redis;
            global $box_sockets;
            //echo $msg . "\n";
            $msg = json_decode($msg, true);
            if (!$msg) {
                $socket->emit('edit', "msg格式不正确");
                return;
            }
            //获取$msg_data中的用户验证信息
            //$auth_key = $msg['token'];
            //获取$msg_data中的edit的数组
            $changed =  json_decode($msg['data'], true);
            if (!$changed) {
                $socket->emit('edit', "data格式不正确");
                return;
            }
            if ($changed['or_txt'] == "<br>") {
                return;
            }
            //获取meeting_id
            $mid = $msg['meeting_id'];
            //获取meeting对应表的lid
            $lid = $redis->hGet('meeting_to_lid', $mid);
            //判断meeting是否储存在对应表id的hash中
            if (!$lid) {
                //如果不存在则
                $socket->emit('edit', "未找到修改文件");
                return;
            }
            //查找哈希 中的数据
            $origin = $redis->hGet($mid, $changed['sorting']);
            if (empty($origin)) {
                $socket->emit('edit', "未找到原始数据");
                return;
            }
            $transfer = json_decode($origin, true);
            if (!$transfer['status']) {
                $socket->emit('edit', "文字状态为未完成，禁止修改");
                return;
            }
            $transfer['ed_txt'] = $changed['ed_txt'];
            if ($transfer['ed_txt'] === "") {
                $transfer['ed_txt'] = " ";
            }
            $edit_data = json_encode($transfer, JSON_UNESCAPED_UNICODE);
            //插入hash和数据库
            $redis->hSet($mid, $changed['sorting'], $edit_data);
            $save = [
                "lid" => $lid,
                //"transfer" => $transfer['or_txt'],
                "editor" => $transfer['ed_txt'],
                //"url" => $transfer['url'],
                //"pcmtime" => $transfer['paly_time'] . '',
                //"sorting" => $transfer['sorting'],
                "update_time" => time()
            ];
            $res = $mysql->update('rszh_meeting_convert')->cols($save)->where("lid = " . $lid . " AND sorting = " . $transfer['sorting'])->query();
            //为rszh_meeting_live_speech的对应数据更新编辑状态
            if (!$redis->hGet($mid . "_state", 'editstate')) {
                $res = $mysql->update('rszh_meeting_live_speech')->cols(['edit_state' => 1])->where("meeting_tag = :mid")->bindValue('mid', $mid)->query();
                $redis->hSet($mid . "_state", 'editstate', 1);
            }
            //盒子端同屏修改
            $res2 = $mysql->select("did,end_time")->from('rszh_meeting_live_speech')->where('meeting_tag= :mid')->bindValues(array('mid' => $mid))->row();
            //获取盒子端的socket
            $box_socket = $box_sockets[$res2['did']];
            if (!empty($box_socket) && empty($res2['endtime'])) {
                //获取全部信息
                $all_message = '';
                $count = $redis->hget($mid . '_state', 'lower') - 1;
                for ($i = $count; $i >= 1; $i--) {
                    if (strlen($all_message) >= 600) {
                        break;
                    }
                    $datas = json_decode($redis->hget($mid, $i), true);
                    $str = $datas['ed_txt'] ? trim($datas['ed_txt']) : trim($datas['or_txt']);
                    if (strlen($str . $all_message) >= 2048) {
                        break;
                    }
                    $last_datas = json_decode($redis->hget($mid, $i - 1), true);
                    if ($datas['sc'] != $last_datas['sc']) {
                        $all_message = ("\n\t" . $str) . $all_message;
                        continue;
                    }
                    $all_message = $str . $all_message;
                }
                if ($n_pos = strpos($all_message, "\n") === 0) {
                    $all_message = substr($all_message, $n_pos);
                }
                //$all_message = substr($all_message, 2);
                //echo $all_message;
                $box_socket->emit('boxedit', $all_message);
            }
            //返回
            if ($res) {
                $data = [
                    "code" => 200,
                    "message" => "修改成功"
                ];
                $socket->emit('edit', $data);
            }
        } catch (\Exception $e) {
            $data = [
                "code" => 400,
                "message" => $e->getMessage()
            ];
            $socket->emit('edit', $data);
            echo $e->getMessage();
        }
    });
});

function sendHistory($mid, $socket)
{
    global $redis, $mysql;
    if (!$mid) {
        echo "获取会议历史，格式不准确";
        return;
    }
    //获取$msg_data中的用户验证信息
    //$auth_key = $msg_data['token'];

    //获取当前录音转写状态
    $lid = $mysql->select('end_time')->from('rszh_meeting_live_speech')->where('meeting_tag = :mid')->bindValues(['mid' => $mid])->query();
    //接收历史记录
    //historical($mid);
    {
        //初始化发送的历史记录接送、字符串
        $dispatch = [];
        $br = [
            'or_txt' => '<br>',
            'ed_txt' => '',
            'url' => '',
            'paly_time' => 0,
            'status' => 1,
            'timestamp' => '',
            'sc' => 0
        ];
        $dispatch[] = json_encode($br);
        //获取结果hash中的结果
        //hVals转换结果乱序
        //$dispatch = $redis->hVals($mid);
        $count = $redis->hget($mid . '_state', 'lower') - 1;
        for ($i = 1; $i <= $count; $i++) {
            $result = $redis->hget($mid, $i);
            $result_la = $redis->hget($mid, $i - 1);
            $result_arr = json_decode($result, true);
            $result_la_arr = json_decode($result_la, true);

            if ($result_arr['sc'] != $result_la_arr['sc']) {
                $br = [
                    'or_txt' => '<br>',
                    'ed_txt' => '',
                    'url' => '',
                    'paly_time' => 0,
                    'status' => 1,
                    'timestamp' => '',
                    'sc' => $result_la_arr['sc'] ? $result_la_arr['sc'] : 0

                    //'sorting' => $sorting + 0,
                ];
                $dispatch[] = json_encode($br);
            }
            $dispatch[] = $redis->hget($mid, $i);
        }
        //返回给连接用户的值
        $data = [
            'list' => $dispatch,
            'total' => count($dispatch)
        ];
    }
    $socket->join($mid);
    $socket->emit('get audio history', $data);
}

$worker = new Worker();

$worker->count = 1;

$worker->onWorkerStart = function () {
    $config = require __DIR__ . '/config.php';
    $redis_sub = new Redis();
    $redis_sub->connect($config['redis']['db_host'], $config['redis']['db_port']);
    $redis_sub->setOption(Redis::OPT_READ_TIMEOUT, -1);
    $redis_sub->subscribe(['send audio info'], 'callback');
};

if (!defined('GLOBAL_START')) {
    Worker::runAll();
}
